/*
 * Copyright (c) 2024. hallele, Inc All rights reserved.
 */

package cn.hallele.infrastructure.data.converter;

import jakarta.persistence.AttributeConverter;
import jakarta.persistence.Converter;

import java.util.Objects;

/**
 * enum类型字段和数据库字段映射的转换类的基础类，做了一些基础的逻辑处理
 *
 * @author anle5
 * @since 2024/7/28 14:24
 */
@Converter
public class BaseEnumConverter<T extends Enum<T> & EnumConverter<C>, C> implements AttributeConverter<T, C> {
    /**
     * 映射类
     */
    protected final Class<T> clazz;

    /**
     * 构造函数
     *
     * @param clazz json类型数据映射的目标java类型
     */
    public BaseEnumConverter(Class<T> clazz) {
        this.clazz = clazz;
    }

    /**
     * Converts the value stored in the entity attribute into the
     * data representation to be stored in the database.
     *
     * @param attribute the entity attribute value to be converted
     * @return the converted data to be stored in the database
     * column
     */
    @Override
    public C convertToDatabaseColumn(T attribute) {
        return attribute == null ? null : attribute.convertToDatabaseColumn();
    }

    /**
     * Converts the data stored in the database column into the
     * value to be stored in the entity attribute.
     * Note that it is the responsibility of the converter writer to
     * specify the correct <code>dbData</code> type for the corresponding
     * column for use by the JDBC driver: i.e., persistence providers are
     * not expected to do such type conversion.
     *
     * @param dbData the data from the database column to be
     *               converted
     * @return the converted value to be stored in the entity
     * attribute
     */
    @Override
    public T convertToEntityAttribute(C dbData) {
        return getT(dbData);
    }

    /**
     * 将数据转换成enum
     *
     * @param dbData dbData
     * @return enum值
     */
    private T getT(C dbData) {
        for (T enumConstant : this.clazz.getEnumConstants()) {
            if (Objects.equals(dbData, enumConstant.convertToDatabaseColumn())) {
                return enumConstant;
            }
        }
        return null;
    }
}
